#include "fun2.cuh"
// #include "check_cuda.h"
#include <iostream>
__global__ void vector_add(float *out, float *a, float *b, int n){
    int id=threadIdx.x;
    out[id] = a[id] + b[id] ;
       // printf("test cuda %f + %f = %f \n",a[id],b[id],out[id]);
//     for(int i=0;i<n;i++)
//     {
//         out[i] = a[i] + b[i] ;
//         printf("test cuda %f + %f = %f \n",a[i],b[i],out[i]);
//     }
}
double fun2::times_ten_to_sqrt(double num)
{
    double ret = fun1::cal_sqrt(num);
    return ret * 10 ;
}

void fun2::useglobal()
{
    std::cout <<"!!!!!!useglobal begins!!!!!"<<std::endl;
    float *a, *b, *out;
    float *d_a, *d_b, *d_out; 

    // Allocate host memory
    a   = (float*)malloc(sizeof(float) * N_test);
    b   = (float*)malloc(sizeof(float) * N_test);
    out = (float*)malloc(sizeof(float) * N_test);

    // Initialize host arrays
    for(int i = 0; i < N_test; i++){
        a[i] = 1.0f;
        b[i] = 2.0f;
    }

    // Allocate device memory
    cudaMalloc((void**)&d_a, sizeof(float) * N_test);
    cudaMalloc((void**)&d_b, sizeof(float) * N_test);
    cudaMalloc((void**)&d_out, sizeof(float) * N_test);
    std::cout <<"dizhi: "<< d_a <<"  "<<d_b<< "  "<<d_out<<std::endl;

    // Transfer data from host to device memory
    cudaMemcpy(d_a, a, sizeof(float) * N_test, cudaMemcpyHostToDevice);
    cudaMemcpy(d_b, b, sizeof(float) * N_test, cudaMemcpyHostToDevice);

    // Executing kernel 
    std::cout<<"vector_add begins"<<std::endl;
    vector_add<<<1,N_test>>>(d_out, d_a, d_b, N_test);
    std::cout<<"vector_add ends"<<std::endl;

    
    // Transfer data back to host memory
    cudaMemcpy(out, d_out, sizeof(float) * N_test, cudaMemcpyDeviceToHost);
    //std::cout<<"d_cout[0] = "<< d_out[0] << std::endl;
    // Verification
    for(int i = 0; i < N_test; i++){
        //std::cout <<out[i] - a[i] - b[i] <<"  "<<MAX_ERR<<std::endl;
        assert(std::abs(out[i] - a[i] - b[i]) < MAX_ERR);
    }
    std::cout << " out[0] = "<< out[0] <<std::endl;

    printf("PASSED\n");

    // Deallocate device memory
    cudaFree(d_a);
    cudaFree(d_b);
    cudaFree(d_out);

    // Deallocate host memory
    free(a); 
    free(b); 
    free(out);

    std::cout <<"!!!!!!useglobal ends!!!!!"<<std::endl;

}

void fun2::setNumber(int num)
{
    number = num ;
}

int fun2::getNumber()
{
    return number;
}